/**
    This header file contains the definitions of locking and synchronization primitives.
    The offered synchronization primitives recall the bahaviour of posix condition variables.
    Condition variable must always be used in conjunction with a lock variable.
    They are realized to be used by two thread only: one that waits and the other that notifies.
    This means that they can be used only in a one-way fashion: A could signal something to B (that
    is waiting), but not viceversa (you need to use two condition variable)

    @author Tiziano De Matteis
*/

#include <stdbool.h>
/* Values used for the synchronization variable*/
#define SYNCHR_VALUE 'a'
#define UNSYNCHR_VALUE 'z'

#ifdef _MWAIT
    #define CACHE_LINE_MONITORED 64 //the size of a cache line monitored my monitor/mwait (byte)
#endif
/**
    Definition of a locking variable
*/
typedef int lock_variable_t;

/**
    Definition of a condition variable for the synchronization between two threads.
    It's simply a wrapper for char *
*/
# ifdef _MWAIT
    /*In this case we have to align it*/
    typedef char cond_variable_t[64] __attribute__ ((aligned (CACHE_LINE_MONITORED)));
#else
    typedef char cond_variable_t ;
#endif


/**
    Spin lock procedure
    @param pointer to a locking variable (of type integer)
*/
inline void spin_lock(lock_variable_t *lV);

/**
    Spin unlock procedure
    @param pointer to a locking variable (of type integer)
*/
inline void spin_unlock(lock_variable_t *lV);

/**
    Signaling procedure on a condition variable.
    @param the condition variable
*/
inline void notify(cond_variable_t *c);

/**
    Waiting procedure on a condition variable. The thread will block
    until the partner notification.
    @param the condition variable and the associated locking variable
*/

inline void waitNotify(cond_variable_t *c, lock_variable_t *l);

/**
    Initializing procedure for a condition variable
    @param pointer to the condition variable
*/
inline void initCondVariable(cond_variable_t *c);

/**
    Initializing procedure for a lock variable
    @param pointer to the locking variable
*/
inline void initLockVariable(lock_variable_t *l);

/**
    Returns whether or not the partner has already notified on the
    condintion variable.
    To be called in a critical section.
    @param pointer to the condition variable
    @param \b true if the partner has already notified, \b false otherwise
*/

inline bool hasAlreadyNotified(cond_variable_t *c);


